(in-package :gwee)

(defclass buffered-mixin ()
  ((cache-surface :accessor buffered-cache))
  (:documentation "Inherit this class to automagically cache the surface which can speed updates."))

(defgeneric save-buffered-view (view)
  (:documentation "The method that actually creates and updates the
cache. This is useful to if you want to modify the cache surface
somehow. ie one with transparency."))

(defmethod save-buffered-view ((view buffered-mixin))
  (unless (and (eql (view-width view) (sdl:width (buffered-cache view)))
	       (eql (view-height view) (sdl:height (buffered-cache view))))
    (setf (buffered-cache view) (sdl:create-surface (view-width obj) (view-height obj))))
  (sdl-base::blit-surface (fp sdl:*default-surface*)
			  (fp (buffered-cache view))
			  (sdl:rectangle :x 0 :y 0
					 :width (view-width view)
					 :height (view-height view))
			  (sdl:rectangle :x (view-cache-top-x view)
					 :y (view-cache-top-y view)
					 :width (view-width view)
					 :height (view-height view))))

(defmethod draw-view :around ((view buffered-mixin))
  (labels ((needs-redraw (view)
	     (or (view-needs-update-p view)
		 (some #'needs-redraw (view-subviews view)))))
    (if (need-redraw view)
	(progn
	  (call-next-method)
	  (buffered-view-save view))
	(sdl:draw-surface-at-* (buffered-cache view)
			       (view-cache-top-x view)
			       (view-cache-top-y view)))))
